package com.gitee.wsl.struct.generator.sample

import com.gitee.wsl.time.toLocalDateTime
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue


/**
 * 激活码生成器单元测试用例
 *
 * @author liuzhaoming
 * @date 2017/11/22
 * @see ActivationCodeGenerator
 */
class ActivationCodeGeneratorTest {
    private val cardIdGenerator: ShopCardIdGenerator = ShopCardIdGenerator()

    private val alphabets: String = ActivationCodeGenerator.generateAlphabets()

    private val codeGenerator: ActivationCodeGenerator = ActivationCodeGenerator(alphabets)


    @Test
    fun generate() {
        val shopId = "A1111"
        for (i in 0..99) {
            val cardId: Long = cardIdGenerator.generate(shopId)
            val code: String = codeGenerator.generate(shopId, cardId)
            assertEquals(12, code.length)
            println(code)
        }
    }

    @Test
    fun validate() {
        val shopId = "A1111"
        val cardId: Long = cardIdGenerator.generate(shopId)
        val code: String = codeGenerator.generate(shopId, cardId)

        assertTrue(codeGenerator.validate(shopId, code))
        assertFalse(codeGenerator.validate("A111", code))
        assertFalse(codeGenerator.validate(shopId, code + "A"))
        val lastChar = code[code.length - 1]
        val newChar = if (lastChar < 'Z') {
            (lastChar.code + 1).toChar()
        } else {
            (lastChar.code - 1).toChar()
        }
        val newCode = code.substring(0, code.length - 2) + newChar
        assertFalse(codeGenerator.validate(shopId, newCode))
    }

    @Test
    fun validateCardId() {
        val shopId = "A1111"
        val cardId: Long = cardIdGenerator.generate(shopId)
        val code: String = codeGenerator.generate(shopId, cardId)
        assertFalse(codeGenerator.validateCardId(code, cardId + 1))
        assertFalse(codeGenerator.validateCardId(code, cardId - 1))
    }

    @Test
    fun testBatch() {
        val shopId = "A1111"
        val alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()

        for (i in 0..999999) {
            val sb = StringBuilder()
            for (j in 0..11) {
                val index: Int = Random.nextInt(26)
                sb.append(alphabet[index])
            }
            if (codeGenerator.validate(shopId, sb.toString())) {
                println(sb.toString() + " : " + codeGenerator.parse(sb.toString()))
            }
        }
    }

    @Test
    fun parse() {
        val shopId = "A1008"
        val code: String = codeGenerator.generate(shopId, 100000000L)
        val results: Array<Long> = codeGenerator.parse(code)!!

        val timestamp = results[0]
        val dateTime = timestamp.toLocalDateTime()
        println("Time: $dateTime")
        println("Machine id: " + results[1])
        println("Sequence: " + results[2])
    }
}